package com.bookocean.application.service;

import com.bookocean.controller.dto.UserProfileDto;
import com.bookocean.controller.dto.BadgeDto;
import com.bookocean.infrastructure.persistence.mapper.UserInfoMapper;
import com.bookocean.infrastructure.persistence.mapper.BadgeDefinitionMapper;
import com.bookocean.infrastructure.persistence.mapper.UserBadgeMapper;
import com.bookocean.infrastructure.persistence.mapper.UserPointsMapper;
import com.bookocean.infrastructure.persistence.po.UserInfoPO;
import com.bookocean.infrastructure.persistence.po.BadgeDefinitionPO;
import com.bookocean.infrastructure.persistence.po.UserBadgePO;
import com.bookocean.infrastructure.persistence.po.UserPointsPO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户档案应用服务（灵曜页面专用）
 * 
 * @author BookOcean
 * @since 2024-01-01
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserProfileApplicationService {

    private final UserInfoMapper userInfoMapper;
    private final BadgeDefinitionMapper badgeDefinitionMapper;
    private final UserBadgeMapper userBadgeMapper;
    private final UserPointsMapper userPointsMapper;

    /**
     * 获取用户完整档案信息（灵曜页面数据）
     * 
     * @param userId 用户ID
     * @return 用户档案信息
     */
    public UserProfileDto getUserProfile(Long userId) {
        log.info("获取用户档案信息，userId: {}", userId);
        
        // 1. 获取用户基本信息
        UserInfoPO userInfo = userInfoMapper.selectById(userId);
        if (userInfo == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 2. 构建用户档案DTO
        UserProfileDto profileDto = new UserProfileDto();
        profileDto.setUserId(userId);
        profileDto.setNickname(userInfo.getNickName());
        profileDto.setAvatarUrl(userInfo.getAvatarUrl());
        profileDto.setTitle(userInfo.getTitle());
        profileDto.setSignature(userInfo.getSignature());
        profileDto.setLevel(userInfo.getLevel());
        profileDto.setCreateTime(userInfo.getCreateTime());
        
        // 3. 构建统计数据
        UserProfileDto.UserStats stats = new UserProfileDto.UserStats();
        stats.setTotalBooks(userInfo.getTotalBooks());
        stats.setTotalPosts(userInfo.getTotalPosts());
        stats.setTotalLikes(userInfo.getTotalLikes());
        stats.setTotalComments(userInfo.getTotalComments());
        stats.setReadingDays(userInfo.getReadingDays());
        profileDto.setStats(stats);
        
        // 4. 获取用户积分信息
        UserPointsPO userPoints = userPointsMapper.selectUserPoints(userId);
        if (userPoints != null) {
            UserProfileDto.UserPoints points = new UserProfileDto.UserPoints();
            points.setTotalPoints(userPoints.getTotalPoints());
            points.setAvailablePoints(userPoints.getAvailablePoints());
            points.setUpdatedAt(userPoints.getUpdatedAt());
            profileDto.setPoints(points);
        }
        
        // 5. 获取用户徽章信息
        List<BadgeDto> badges = getUserBadges(userId);
        profileDto.setBadges(badges);
        
        return profileDto;
    }

    /**
     * 获取用户徽章列表
     * 
     * @param userId 用户ID
     * @return 徽章列表
     */
    public List<BadgeDto> getUserBadges(Long userId) {
        log.info("获取用户徽章列表，userId: {}", userId);
        
        // 1. 获取所有徽章定义
        List<BadgeDefinitionPO> allBadges = badgeDefinitionMapper.selectActiveBadges();
        
        // 2. 获取用户已获得的徽章
        List<UserBadgePO> userBadges = userBadgeMapper.selectUserBadges(userId);
        Map<Long, UserBadgePO> userBadgeMap = userBadges.stream()
                .collect(Collectors.toMap(UserBadgePO::getBadgeId, badge -> badge));
        
        // 3. 构建徽章DTO列表
        List<BadgeDto> badgeDtos = new ArrayList<>();
        for (BadgeDefinitionPO badgeDef : allBadges) {
            BadgeDto badgeDto = new BadgeDto();
            badgeDto.setBadgeId(badgeDef.getBadgeId());
            badgeDto.setName(badgeDef.getName());
            badgeDto.setDescription(badgeDef.getDescription());
            badgeDto.setIconUrl(badgeDef.getIconUrl());
            badgeDto.setCategory(badgeDef.getCategory());
            badgeDto.setRequirement(badgeDef.getRequirement());
            
            // 检查用户是否已获得该徽章
            UserBadgePO userBadge = userBadgeMap.get(badgeDef.getBadgeId());
            if (userBadge != null) {
                badgeDto.setObtained(true);
                badgeDto.setEarnedAt(userBadge.getEarnedAt());
                badgeDto.setIsVisible(userBadge.getIsVisible());
            } else {
                badgeDto.setObtained(false);
                badgeDto.setIsVisible(false);
            }
            
            badgeDtos.add(badgeDto);
        }
        
        return badgeDtos;
    }

    /**
     * 更新用户个性签名
     * 
     * @param userId 用户ID
     * @param signature 个性签名
     * @return 更新结果
     */
    public boolean updateUserSignature(Long userId, String signature) {
        log.info("更新用户个性签名，userId: {}, signature: {}", userId, signature);
        
        UserInfoPO userInfo = new UserInfoPO();
        userInfo.setId(userId);
        userInfo.setSignature(signature);
        userInfo.setUpdateTime(LocalDateTime.now());
        
        int result = userInfoMapper.updateById(userInfo);
        return result > 0;
    }

    /**
     * 记录用户协议同意
     * 
     * @param agreementData 协议同意数据
     * @return 记录结果
     */
    public boolean recordUserAgreement(com.bookocean.controller.dto.UserAgreementDto agreementData) {
        log.info("记录用户协议同意，userId: {}, agreementType: {}, version: {}", 
                agreementData.getUserId(), agreementData.getAgreementType(), agreementData.getAgreementVersion());
        
        try {
            // 先检查用户是否已经同意过该协议
            int existingCount = userInfoMapper.countAgreementRecords(
                agreementData.getUserId(), 
                agreementData.getAgreementType(), 
                agreementData.getAgreementVersion()
            );
            
            if (existingCount > 0) {
                log.info("用户已存在协议记录，无需重复插入。userId: {}, agreementType: {}, version: {}", 
                        agreementData.getUserId(), agreementData.getAgreementType(), agreementData.getAgreementVersion());
                return true;
            }
            
            // 解析同意时间 - 处理ISO格式时间
            LocalDateTime agreedAt;
            String agreedAtStr = agreementData.getAgreedAt();
            if (agreedAtStr.contains("T")) {
                // ISO格式：2024-01-01T12:00:00.000Z
                agreedAt = LocalDateTime.parse(agreedAtStr.substring(0, 19));
            } else {
                // 其他格式，使用当前时间
                agreedAt = LocalDateTime.now();
            }
            
            // 插入新的协议记录
            int result = userInfoMapper.insertAgreementRecord(
                agreementData.getUserId(),
                agreementData.getAgreementType(),
                agreementData.getAgreementVersion(),
                agreedAt,
                agreementData.getUserAgent(),
                agreementData.getAppVersion()
            );
            
            if (result > 0) {
                log.info("用户协议记录插入成功。userId: {}, agreementType: {}, version: {}", 
                        agreementData.getUserId(), agreementData.getAgreementType(), agreementData.getAgreementVersion());
                return true;
            } else {
                log.warn("用户协议记录插入失败，影响行数为0。userId: {}, agreementType: {}, version: {}", 
                        agreementData.getUserId(), agreementData.getAgreementType(), agreementData.getAgreementVersion());
                return false;
            }
        } catch (Exception e) {
            log.error("记录用户协议同意失败", e);
            return false;
        }
    }

    /**
     * 检查用户是否已同意协议
     * 
     * @param userId 用户ID
     * @param agreementType 协议类型
     * @param agreementVersion 协议版本（可选）
     * @return 是否已同意
     */
    public boolean checkUserAgreement(Long userId, String agreementType, String agreementVersion) {
        log.info("检查用户协议同意状态，userId: {}, agreementType: {}, version: {}", 
                userId, agreementType, agreementVersion);
        
        try {
            // 查询用户是否已同意指定协议
            int count = userInfoMapper.countAgreementRecords(userId, agreementType, agreementVersion);
            return count > 0;
        } catch (Exception e) {
            log.error("检查用户协议同意状态失败", e);
            return false;
        }
    }

    /**
     * 获取用户积分信息
     * 
     * @param userId 用户ID
     * @return 用户积分信息
     */
    public UserProfileDto.UserPoints getUserPoints(Long userId) {
        log.info("获取用户积分信息，userId: {}", userId);
        
        UserPointsPO userPoints = userPointsMapper.selectUserPoints(userId);
        if (userPoints == null) {
            // 如果用户没有积分记录，创建默认记录
            userPoints = new UserPointsPO();
            userPoints.setUserId(userId);
            userPoints.setTotalPoints(0);
            userPoints.setAvailablePoints(0);
            userPoints.setCreatedAt(LocalDateTime.now());
            userPoints.setUpdatedAt(LocalDateTime.now());
            userPointsMapper.insert(userPoints);
        }
        
        UserProfileDto.UserPoints pointsDto = new UserProfileDto.UserPoints();
        pointsDto.setTotalPoints(userPoints.getTotalPoints());
        pointsDto.setAvailablePoints(userPoints.getAvailablePoints());
        pointsDto.setUpdatedAt(userPoints.getUpdatedAt());
        
        return pointsDto;
    }
}
